package com.csii.mca.service.lqd.service.impl;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionOperations;

import com.csii.common.constants.MChannel;
import com.csii.common.constants.business.LqdEndRateListConstants;
import com.csii.common.constants.business.LqdStartRateListConstants;
import com.csii.epublish.service.euser.EuserService;
import com.csii.epublish.service.land.LandService;
import com.csii.epublish.service.lqd.AuditService;
import com.csii.epublish.service.lqd.LqdService;
import com.csii.mca.base.datamodel.Ecusr;
import com.csii.mca.datamodel.LqdBillAccountInfo;
import com.csii.mca.datamodel.LqdBillEndrateInfo;
import com.csii.mca.datamodel.LqdBillEndratePrdDetail;
import com.csii.mca.datamodel.LqdBillStartrateInfo;
import com.csii.mca.datamodel.LqdBillInfo;
import com.csii.mca.service.MCCallbackService;
import com.csii.mca.service.lqd.datemodel.MCALqdQsDaoqiPrdListConfirmRequest;
import com.csii.mca.service.lqd.datemodel.MCALqdQsDaoqiPrdListConfirmResponse;
import com.csii.mca.service.lqd.service.MCALqdQsDaoqiPrdListConfirmService;
import com.csii.mca.service.lqd.utils.utils;
import com.csii.mcs.core.CHECKMSG;
import com.csii.mcs.core.CONSMSG;
import com.csii.mcs.core.util.Util;
import com.csii.pe.common.util.BeanUtils;
import com.csii.pe.common.util.CsiiUtils;
import com.csii.pe.core.PeRuntimeException;
import com.csii.pe.dynamic.service.ProcessState;
import com.csii.pe.dynamic.service.RequestContext;
import com.csii.pe.service.id.IdFactory;
import com.csii.pe.service.id.NewUUIDFactory;

/**
 * 
 * Description: 制到期单
 * 1.在继承的模版中，启动工作流
 * 2.组装要入表的信息，入的表分别是LQD_BILL_ACCOUNT_INFO，LQD_BILL_ENDRATE_INFO，LQD_BILL_ENDRATE_PRD_DETAIL
 * 3.放到事物里面入表
 * 4.到鑫管理平台执行审核再走：同意notifySubmit，拒绝notifyOther
 * 
 * Copyright (c) XHEJ.
 * All Rights Reserved.
 * <Strong>主要的类使用</Strong>如何使用该类, 包括环境要求,如是否线程安全,并发性要求, 以及使用约束
 * <Strong>已知的BUG</Strong>
 * UPDATE-HISTORY:<Strong>修改人+日期＋简单说明</Strong>
 * @version 1.0  2017-3-18 上午11:19:21  by liziyue (liziyue@goldenfintech.com.cn)
 * @see Action
 */
public class MCALqdQsDaoqiPrdListConfirmServiceImpl extends MCCallbackService<MCALqdQsDaoqiPrdListConfirmRequest, MCALqdQsDaoqiPrdListConfirmResponse> implements MCALqdQsDaoqiPrdListConfirmService {
	private LqdService lqdService;
	
	private EuserService euserService;
	/**获取uuid*/
	private NewUUIDFactory newUUIDFactory;
	
	private IdFactory accountSeqFactory;
	/**引入事物*/
	private TransactionOperations trsTemplate;
	
	/** 审核用接口 */
	private AuditService auditService;
	/** 落地金额判断接口 */
	private LandService landService;
	/** 常量落地金额阀值 */
	private static final String Threshold="Threshold"; 
	/** 划款单状态 */
	private static final String BillStatus="BillStatus"; 

	private String fKnjbankAccountNO;
	
	private String fKnjbankDepositeBank;
	
	private String fKnjbankAccountName;
	
	private String fKnjbankDepositeBankName;
	
	@SuppressWarnings("unchecked")
	@Override
	protected MCALqdQsDaoqiPrdListConfirmResponse notifyInit(MCALqdQsDaoqiPrdListConfirmRequest request,
			RequestContext originRequestContext) {
		MCALqdQsDaoqiPrdListConfirmResponse response = new MCALqdQsDaoqiPrdListConfirmResponse();
		Map<String, Object> queryMap = new HashMap<String, Object>();
		queryMap.put("MChannelId", originRequestContext.getRequestMChannelId());
		queryMap.put("CifSeq", originRequestContext.getRequestCifSeq());
		queryMap.put("BusiSeq", request.getBusiSeq());
		queryMap.put("TransId", request.getTransId());
		// 取得当前审核模版，包含各级别复核人数，复核模版
		Map<String, Object> authSetting = (Map<String, Object>)this.sqlMap.queryForObject("queryShentacauthQuery", queryMap);
		if(authSetting==null || authSetting.isEmpty()){
			throw new PeRuntimeException(CHECKMSG.VALIDATION_TASK_AUDIT_NOT_EXIST);
		}
		String uuid = originRequestContext.getRequestJnlNo().toString();
		final LqdBillEndrateInfo lqdBill = getLqdBillEndrateInfo(request, uuid);
		final List<LqdBillEndratePrdDetail> lqdBillDetail = getLqdBillEndratePrdDetail(request, uuid);
		final List<LqdBillAccountInfo> lqdBillAcc = getLqdBillAccountInfo(request, uuid);
		//校验单据帐号
		if(!checkAccount(lqdBillAcc.get(0))){
			throw new PeRuntimeException(CHECKMSG.BANKNO_AND_BANKNAME_MATCH_ERROR);
		}
		this.trsTemplate.execute(new TransactionCallback() {
			//事物
			@Override
			public Object doInTransaction(TransactionStatus arg0) {
					
					//添加起息单信息表
					lqdService.insertBillEndRateInfo(lqdBill);
	        		//添加起息单产品明细表
					lqdService.insertBillEndRatePrdDetail(lqdBillDetail);
	        		//添加单据账户信息表
					lqdService.insertBillAccountInfo(lqdBillAcc);
				return null;
			}
		});
		return response;
	}
	
	
	
	/**
	 * 主要处理: 审核结束业务控制(到期单)
	 * 2017/03/12  wangjianghui inset
	 */
	@SuppressWarnings("unchecked")
	@Override
	protected MCALqdQsDaoqiPrdListConfirmResponse notifySubmit(
			MCALqdQsDaoqiPrdListConfirmRequest request,
			RequestContext originRequestContext) { 
		
		MCALqdQsDaoqiPrdListConfirmResponse response = new MCALqdQsDaoqiPrdListConfirmResponse();
		// 1:不需要落地处理，将BILL_STATUS变为3划款中（默认不需要落地）
		String billStatus =CONSMSG.BILL_STATUS_3;
		
		Map<String,Object>  paramMap = BeanUtils.bean2Map(request);
		paramMap.put("LqdUuid", originRequestContext.getRequestJnlNo().toString());
		
		// 2:查询当前订单的概要信息
		List<Map<String, Object>> list=this.auditService.groundTreatmentQuery(paramMap);
		
		// 3:调用落地落地金额判断接口，查看当前订单是否需要落地
		paramMap.put(Threshold, list.get(0).get("money"));
		if(this.landService.queryLandThresholdInfo(paramMap)){
			// 4:需要落地处理， 将BILL_STATUS状态变为 2审批通过
			billStatus=CONSMSG.BILL_STATUS_2;
		} 
		paramMap.put(BillStatus, billStatus);
		
		// 5.当单据类型为Q时更新起息单信息表
//		if(list.get(0).getBillType().equals(CONSMSG.BILL_TYPE_Q)){
//			// 更新起息单 updateInterestNote()
//			this.auditService.updateInterestNote(paramMap);
//			
//		}
		// 6:当单据类型为D时更新到期单信息表
//		if(list.get(0).getBillType().equals(CONSMSG.BILL_TYPE_D)){
//			// 更新到期单updateDueNote()
			this.auditService.updateDueNote(paramMap);
//			
//		}
		return response;
	}

	/**
	 * 
	 * Description: 当审核拒绝时走这个方法
	 * <Strong>使用场景</Strong>
	 * <Strong>已知bug</Strong>
	 * <Strong>修改人+日期＋简单说明</Strong> (<修改人+日期＋简单说明>)
	 * @param 
	 * @return 
	 * @throws
	 * @see
	 * @see com.csii.mca.service.MCCallbackService#notifyOther(com.csii.pe.dynamic.service.ProcessState, java.lang.Object, com.csii.pe.dynamic.service.RequestContext)
	 * @Version1.0 2017-3-15 下午08:18:56 by liziyue (liziyue@goldenfintech.com.cn)
	 */
	@SuppressWarnings("unchecked")
	protected MCALqdQsDaoqiPrdListConfirmResponse notifyOther(ProcessState processState, MCALqdQsDaoqiPrdListConfirmRequest request, RequestContext originRequestContext)
	{
		if (ProcessState.RJ.equals(processState)) {
			MCALqdQsDaoqiPrdListConfirmResponse response = new MCALqdQsDaoqiPrdListConfirmResponse();
			// 1:不需要落地处理，将BILL_STATUS变为3划款中（默认不需要落地）
			String billStatus =CONSMSG.BILL_STATUS_9;
			
			Map<String,Object>  paramMap = BeanUtils.bean2Map(request);
			paramMap.put("LqdUuid", originRequestContext.getRequestJnlNo().toString());
			
			// 2:查询当前订单的概要信息
			List<Map<String, Object>> list=this.auditService.groundTreatmentQuery(paramMap);
			
			// 3:调用落地落地金额判断接口，查看当前订单是否需要落地
			paramMap.put(Threshold, list.get(0).get("money"));
//			if(this.landService.queryLandThresholdInfo(paramMap)){
				// 4:需要落地处理， 将BILL_STATUS状态变为 2审批通过
//				billStatus=CONSMSG.BILL_STATUS_2;
//			} 
			paramMap.put(BillStatus, billStatus);
			
			// 5.当单据类型为Q时更新起息单信息表
//			if(list.get(0).getBillType().equals(CONSMSG.BILL_TYPE_Q)){
//				// 更新起息单 updateInterestNote()
//				this.auditService.updateInterestNote(paramMap);
//				
//			}
			// 6:当单据类型为D时更新到期单信息表
//			if(list.get(0).getBillType().equals(CONSMSG.BILL_TYPE_D)){
//				// 更新到期单updateDueNote()
			this.auditService.updateDueNote(paramMap);
//				
//			}
			return response;
		}
		super.notifyOther(processState, request, originRequestContext);
		
		return null;
		
	}
	
	public LqdService getLqdService() {
		return lqdService;
	}

	public void setLqdService(LqdService lqdService) {
		this.lqdService = lqdService;
	}

	public EuserService getEuserService() {
		return euserService;
	}

	public void setEuserService(EuserService euserService) {
		this.euserService = euserService;
	}

	public NewUUIDFactory getNewUUIDFactory() {
		return newUUIDFactory;
	}

	public void setNewUUIDFactory(NewUUIDFactory newUUIDFactory) {
		this.newUUIDFactory = newUUIDFactory;
	}

	public IdFactory getAccountSeqFactory() {
		return accountSeqFactory;
	}

	public void setAccountSeqFactory(IdFactory accountSeqFactory) {
		this.accountSeqFactory = accountSeqFactory;
	}

	public TransactionOperations getTrsTemplate() {
		return trsTemplate;
	}

	public void setTrsTemplate(TransactionOperations trsTemplate) {
		this.trsTemplate = trsTemplate;
	}
	//组装LqdBillEndrateInfo
	public LqdBillEndrateInfo getLqdBillEndrateInfo(MCALqdQsDaoqiPrdListConfirmRequest request, String uuid){
		LqdBillEndrateInfo lqd = new LqdBillEndrateInfo();
		SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
		//清算业务流水号
		lqd.setLqdUuid(uuid);
		//到期单流水号
		StringBuffer sb = new StringBuffer();
		sb.append("D00001501");
		Date date = new Date();
		sb.append(sdf.format(date));
		sb.append(utils.getRandomLenStr(5));
		String busiJnlSeq = CsiiUtils.getString(sb);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("busiJnlSeq", busiJnlSeq);
		//取随机数有可能相同，这里是保证busiJnlSeq不同
		int l = 0;
		do{
			List<LqdBillStartrateInfo> list = this.lqdService.queryLqdBillStartrateInfo(map);
			l = list.size();
			if(list.size() > 0){
				sb.delete(sb.length()-5, sb.length());
				sb.append(utils.getRandomLenStr(5));
				busiJnlSeq = CsiiUtils.getString(sb);
				map.put("busiJnlSeq", busiJnlSeq);
			}
		}while( l != 0);
		lqd.setBusiJnlSeq(busiJnlSeq);
		//模块渠道代号
		lqd.setMchannelId(MChannel.EFOP.toString());
		//划款日期-对应产品到期日
		String endDate = request.getEndDate();
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			lqd.setPanmentDate(sf.parse(endDate));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		//业务类型
		lqd.setBusiType("1501");
		//交易方机构编号
		String userSeq = request.getUserSeq();
		Ecusr user = this.euserService.queryUserInfo(userSeq);
		lqd.setCifseqCharge(CsiiUtils.getString(user.getCifSeq()));
		//对手方机构编号
		String otherOrg = request.getOtherOrg();
		lqd.setCifseqOpponent(otherOrg);
		//金额
		double totalMoney = request.getTotalMoney();
		lqd.setMoney(new BigDecimal(totalMoney));
		//手续费
		
		//划款单状态
		lqd.setBillStatus(LqdEndRateListConstants.BILL_STATUS_1);
		//划款单审批状态
		lqd.setBillAuditStatus(LqdEndRateListConstants.BILL_AUDIT_STATUS_0);
		//划款单申请人
		lqd.setBillAppliUserseq(userSeq);
		//支付业务编号-支付系统返回时填入(此处不填)
		//创建时间-系统时间
		//创建人
		lqd.setCreateUser(userSeq);
		//最新修改时间-系统时间
		//最新修改人
		lqd.setUpdateUser(userSeq);
		//计算出总金额
		lqd.setMoneyTotalTemp(request.getMoneyTotalTemp());
		return lqd;
	}
	
	//组装LqdBillEndratePrdDetail
	public List<LqdBillEndratePrdDetail> getLqdBillEndratePrdDetail(MCALqdQsDaoqiPrdListConfirmRequest request, String uuid){
		List<LqdBillEndratePrdDetail> lqdList = new ArrayList<LqdBillEndratePrdDetail>();
		String list = request.getList();
		String[] newList = list.split(",");
		for(int i = 0; i < newList.length; i++){
			LqdBillEndratePrdDetail lqd = new LqdBillEndratePrdDetail();
			//产品明细序列号
			String pubSeqDetail = newList[i].split("\\^")[1];
			lqd.setPubSeqDetail(pubSeqDetail);
			//清算业务流水号
			lqd.setLqdUuid(uuid);
			//应答流水编号-单条产品的pubSeq
			String pubSeq = newList[i].split("\\^")[0];
			lqd.setPubSeq(pubSeq);
			
			HashMap<String, Object> map = new HashMap<String, Object>();
			map.put("ResState", LqdEndRateListConstants.res_State);
			map.put("PubSeq", pubSeq);
			map.put("PubSeqDetail", pubSeqDetail);
			map.put("UserSeq", request.getUserSeq());
			map.put("DealDerct", LqdEndRateListConstants.DEAL_DERCT_2);
			map.put("AccountType", request.getAccountType());
			List<LqdBillInfo> detail = this.lqdService.queryFinanceprodconsigDq(map);
			if(Util.isNullOrEmpty(detail)){
				throw new PeRuntimeException(CHECKMSG.VALIDATION_PUBSEQ_NOT_EXIST);
			}
			LqdBillInfo jrcpDetail = detail.get(0);
			//产品代码
			String prdCode = jrcpDetail.getPrdCode();
			lqd.setPrdCode(prdCode);
			//名称/简称
			String nameCode = jrcpDetail.getNameCode();
			lqd.setNameCode(nameCode);
			//交易金额
			BigDecimal originMoney = jrcpDetail.getOriginMoney();
			lqd.setOriginMoney(originMoney);
			//币种
			String currency = jrcpDetail.getCurrency();
			lqd.setCurrency(currency);
			//金额单位
			String moneyUnit = jrcpDetail.getMoneyUnit();
			lqd.setMoneyUnit(moneyUnit);
			//金额（规模）
			BigDecimal money = jrcpDetail.getMoney();
			lqd.setMoney(money);
			//发行期限
			String deadLineDay = jrcpDetail.getDeadlineDay();
			lqd.setDeadlineDay(deadLineDay);
			//期限类型
			String deadLineDayValue = jrcpDetail.getDeadlineDayValue();
			lqd.setDeadlineDayValue(deadLineDayValue);
			//起息日
			Date startRateDate = jrcpDetail.getStartRateDate();
			lqd.setStartRateDate(startRateDate);
			//到息日
			Date endRateDate = jrcpDetail.getEndRateDate();
			lqd.setEndRateDate(endRateDate);
			//票面利率
			BigDecimal moneyRate = jrcpDetail.getMoneyRate();
			lqd.setMoneyRate(moneyRate);
			//手续费率
			BigDecimal fee = jrcpDetail.getFee();
			lqd.setFee(fee);
			//评级
			String grade = jrcpDetail.getGrade();
			lqd.setGrade(grade);
			//分级
			String classify = jrcpDetail.getClassify();
			lqd.setClassify(classify);
			//单家代销金额限制
			String limitMoney = jrcpDetail.getLimitMoney();
			if(limitMoney != null && limitMoney != ""){
				BigDecimal limitMon = new BigDecimal(limitMoney);
				limitMon = limitMon.multiply(new BigDecimal(10000));
				lqd.setLimitMoney(limitMon);
			}
			//笔数
			String pensNum = jrcpDetail.getPensNum();
			lqd.setPensNum(pensNum);
			//募集开始日期
			Date modStartTime = jrcpDetail.getModStartTime();
			lqd.setModStartTime(modStartTime);
			//募集结束日期
			Date modEndTime = jrcpDetail.getModEndTime();
			lqd.setModEndTime(modEndTime);
			//认购起点
			BigDecimal purchPoint = jrcpDetail.getPurchPoint();
			if(purchPoint != null)
				lqd.setPurchPoint(purchPoint.multiply(new BigDecimal(10000)));
			//发布消息客户经理序列号
			String publishUserSeq = request.getUserSeq();
			lqd.setPublishUserSeq(publishUserSeq);
			//修改时间-系统时间
			//手续费
			String feeMoney = jrcpDetail.getFeeMoney();
			BigDecimal fMoney = new BigDecimal(0);
			if(feeMoney!=null||feeMoney!=""){
				fMoney = new BigDecimal(feeMoney);
			}
			lqd.setFeeMoney(fMoney);
			//收益
			String income = jrcpDetail.getIncome();
			BigDecimal iMoney = new BigDecimal(0);
			if(income!=null||income!=""){
				iMoney = new BigDecimal(income);
			}
			lqd.setEarnMoney(iMoney);
			//划款金额
			String totalMoney = jrcpDetail.getTotalMoney();
			BigDecimal tMoney = new BigDecimal(0);
			if(totalMoney!=null||totalMoney!=""){
				tMoney = new BigDecimal(totalMoney);
			}
			lqd.setPayMoney(tMoney);
			//塞入list
			lqdList.add(lqd);
		}
		//产品代码
		return lqdList;
	}
	
	//组装LqdBillAccountInfo
	public List<LqdBillAccountInfo> getLqdBillAccountInfo(MCALqdQsDaoqiPrdListConfirmRequest request, String uuid){
		List<LqdBillAccountInfo> lqdList = new ArrayList<LqdBillAccountInfo>();
		/**
		 * 对手方账号
		 */
		LqdBillAccountInfo lqd = new LqdBillAccountInfo();
		//账户信息编号
		long accountSeq = Long.parseLong(getAccountSeqFactory().generate().toString());
		lqd.setAccountSeq(CsiiUtils.getString(accountSeq));
		//清算业务流水号
		lqd.setLqdUuid(uuid);
		//账户类型
		String accountType = request.getAccountType();
		lqd.setAccountType(accountType);
		//户名
		String accountName = request.getAccountName();
		lqd.setAccountName(accountName);
		//大额支付号
		String bigMoneyAccount = request.getBigMoneyAccount();
		lqd.setLargePaymentNo(bigMoneyAccount);
		//帐号
		String account = request.getAccount();
		lqd.setAccount(account);
		//开户行
		String bankOfOpen = request.getBankOfOpen();
		lqd.setDepositBank(bankOfOpen);
		//最新修改时间-系统时间
		//最新修改人
		String userSeq = request.getUserSeq();
		lqd.setUpdateUser(userSeq);
		//账号方向
		lqd.setAccountDerct(request.getOtherOrg());
		lqdList.add(lqd);
		/**
		 * 己方账号
		 */
		LqdBillAccountInfo lqd1 = new LqdBillAccountInfo();
		//账户信息编号
		long accountSeq1 = Long.parseLong(getAccountSeqFactory().generate().toString());
		lqd1.setAccountSeq(CsiiUtils.getString(accountSeq1));
		//清算业务流水号
		lqd1.setLqdUuid(uuid);
		//账户类型
		lqd1.setAccountType(LqdStartRateListConstants.BILL_ACCOUNT_TYPE_1);
		//户名
		String accountName1 = fKnjbankAccountName;
		lqd1.setAccountName(accountName1);
		//大额支付号
		String bigMoneyAccount1 = fKnjbankDepositeBank;
		lqd1.setLargePaymentNo(bigMoneyAccount1);
		//帐号
		String account1 = fKnjbankAccountNO;
		lqd1.setAccount(account1);
		//开户行
		String bankOfOpen1 = fKnjbankDepositeBankName;
		lqd1.setDepositBank(bankOfOpen1);
		//最新修改时间-系统时间
		//最新修改人
		lqd1.setUpdateUser(userSeq);
		//账号方向
		Ecusr user1 = this.euserService.queryUserInfo(userSeq);
		lqd1.setAccountDerct(user1.getCifSeq().toString());
		lqdList.add(lqd1);
		return lqdList;
	}

	// 查询单据原始数据
	@Override
	public MCALqdQsDaoqiPrdListConfirmRequest restore(Long taskSeq) {
		@SuppressWarnings("unchecked")
		Map<String, Object> map = (Map<String, Object>)this.sqlMap.queryForObject("restoreMCALqdQingsuanHuiPrdListConfirmRequest", taskSeq.toString());
		MCALqdQsDaoqiPrdListConfirmRequest request = BeanUtils.map2Bean(map, MCALqdQsDaoqiPrdListConfirmRequest.class);
		return request;
	}

	public AuditService getAuditService() {
		return auditService;
	}

	public void setAuditService(AuditService auditService) {
		this.auditService = auditService;
	}

	public LandService getLandService() {
		return landService;
	}

	public void setLandService(LandService landService) {
		this.landService = landService;
	}
	
	public String getfKnjbankAccountNO() {
		return fKnjbankAccountNO;
	}

	public void setfKnjbankAccountNO(String fKnjbankAccountNO) {
		this.fKnjbankAccountNO = fKnjbankAccountNO;
	}

	public String getfKnjbankDepositeBank() {
		return fKnjbankDepositeBank;
	}

	public void setfKnjbankDepositeBank(String fKnjbankDepositeBank) {
		this.fKnjbankDepositeBank = fKnjbankDepositeBank;
	}

	public String getfKnjbankAccountName() {
		return fKnjbankAccountName;
	}

	public void setfKnjbankAccountName(String fKnjbankAccountName) {
		this.fKnjbankAccountName = fKnjbankAccountName;
	}

	public String getfKnjbankDepositeBankName() {
		return fKnjbankDepositeBankName;
	}

	public void setfKnjbankDepositeBankName(String fKnjbankDepositeBankName) {
		this.fKnjbankDepositeBankName = fKnjbankDepositeBankName;
	}

	//校验账号
	public boolean checkAccount(LqdBillAccountInfo lqdAcc){
		boolean flag = true;
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("BankName", lqdAcc.getDepositBank());
		map.put("BankNo", lqdAcc.getLargePaymentNo());
		int i = (Integer) this.sqlMap.queryForObject("checkAccountInfo", map);
		if(i == 0){
			flag = false;
		}
		return flag;
	}
}
